package network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpEchoServer {
    private DatagramSocket socket = null;

    public UdpEchoServer(int port) throws SocketException {
        //创建socket的对象时，需要指定端口号作为构造方法的参数，port就是端口号，有了端口号才会和后续进程进行关联。
        socket = new DatagramSocket(port);
        //调用构造方法的过程中，JVM就会调用系统的socket API完成端口号和进程之间的关联动作
        //一个端口号只能绑定一个进程，一个进程可以绑定多个端口号（创建多个socket）
    }

    //调用start的方法启动服务器
    public void start() throws IOException {
        System.out.println("服务器启动！");
        while (true) {
            //1.读取客户端的请求并解析
            //receive是从网卡上读取数据，当网卡没有数据时，receive会阻塞等待，有数据时，receive直接返回数据
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(requestPacket);
            //上述收到的数据是二进制byte[]的形式体现的，后续代码需要打印之类的处理操作，需要转换成字符串
            String request = new String(requestPacket.getData(),0, requestPacket.getLength());

            //2.根据请求计算响应  （此处是回显服务器,响应就是请求)
            String response = process(request);

            //3.把响应返回客户端
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
                    requestPacket.getSocketAddress());
            //UDP是无连接，需要通信双方保存对方的信息（IP + 端口号），DatagramSocket这个对象中，不支持对方（客户端）的IP和端口号
            //进行send的时候就需要在send的数据包里，把要发给谁这样的信息，写进去，才能够正确的将数据传回
            //requestPacket.getSocketAdrress就是包含客户端的IP和端口号
            socket.send(responsePacket);

            //4.打印日志
            System.out.printf("[%s:%d] request = %s, response = %s\n",requestPacket.getAddress(),requestPacket.getPort()
            ,request,response);
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer server = new UdpEchoServer(8080);
        server.start();
    }

}
